import 'package:sqflite/sqflite.dart';
import 'package:xreader/common/app_config.dart';
import 'package:xreader/common/dxm_utils.dart';
import 'package:xreader/db/base_db_provider.dart';
import 'package:xreader/logs/log.dart';
import 'package:xreader/model/t_book_entity.dart';
import 'package:xreader/params/book_params.dart';

class TBookProvider extends BaseDbProvider {
  static final String TABLE_NAME = AppConfig.t_book;
  static final String column_id = "id";
  static final String column_phk = "phk";
  static final String column_bname = "bname";
  static final String column_bauthor = "bauthor";
  static final String column_bchao = "bchao";
  static final String column_bcount = "bcount";
  static final String column_bstatus = "bstatus";
  static final String column_border = "border";
  static final String column_bsign = "bsign";
  static final String column_bdesc = "bdesc";
  static final String column_tmsec = "tmsec";
  Map<String,dynamic> toMap(TBookEntity po){
    Map<String,dynamic> info = {
      column_id:po.id,
      column_phk:po.phk,
      column_bname:po.bname,
      column_bauthor:po.bauthor,
      column_bchao:po.bchao,
      column_bcount:po.bcount,
      column_bstatus:po.bstatus,
      column_border:po.border,
      column_bsign:po.bsign,
      column_bdesc:po.bdesc,
      column_tmsec:po.tmsec,
    };
    return info;
  }

  @override
  List<String> tableIndexString() {
    List<String> indexs = <String>[];
    indexs.add(
     '''
        create index ${TABLE_NAME}_border_idx on ${TABLE_NAME} ( ${column_border} COLLATE BINARY ASC )
     '''
    );
    return indexs;
  }

  @override
  String tableName() {
    return  TABLE_NAME;
  }

  @override
  String tableSqlString() {
    return '''${tableBaseStringIntegerPrimarkKey(TABLE_NAME, column_id)}        $column_phk text,
        $column_bname text,
        $column_bauthor text,
        $column_bchao text,
        $column_bcount integer,
        $column_bstatus integer,
        $column_border integer,
        $column_bsign text,
        $column_bdesc text,
        $column_tmsec integer
        )
      ''';
  }

  ///批量插入
  ///已经存在则更新记录
  insertOrUpdateBatch(List<TBookEntity>? datas) async{
    if(datas == null || datas.isEmpty){
      return;
    }
    Database? db = await getDataBase();
    if(db == null){
      return;
    }
    var batch = db.batch();
    datas.forEach((info) {
      batch.insert(TABLE_NAME, toMap(info),conflictAlgorithm: ConflictAlgorithm.replace);
    });
    await batch.commit(noResult: true);
  }

  //同步远程书籍排序到本地
  updateBorderMap(Map<int,int> borderMap) async {
    if(borderMap.isEmpty){
      return;
    }
    Database? db = await getDataBase();
    if(db == null){
      return;
    }
    var batch = db.batch();
    borderMap.forEach((key, value) {
      batch.update(tableName(), {"$column_border":value},where: " $column_id = ? ",whereArgs: [key]);
    });
    await batch.commit(noResult: true);
  }

  /// 获取全部id排序号
  Future<Map<int,int>> getAllIdOrderByBorder() async {
    Database? db = await getDataBase();
    if(db == null){
      return {};
    }
    Map<int,int> result = {};
    List<Map<String, Object?>> dbRecords = await db.rawQuery("select id,border from ${tableName()} order by $column_border asc ");
    for(Map<String, Object?> obj in dbRecords){
      TBookEntity bookEntity = TBookEntity.fromJson(obj);
      result[bookEntity.id ?? 0] = bookEntity.border ?? 0;
    }
    return result;
  }

  /// 获取基本信息数据
  Future<List<TBookEntity>> getAllBaseData() async {
    Database? db = await getDataBase();
    if(db == null){
      return [];
    }
    List<Map<String, Object?>> dbRecords = await db.rawQuery("select id,border,bsign from ${TABLE_NAME} ");
    List<TBookEntity> datas = [];
    for(Map<String, Object?> obj in dbRecords){
      TBookEntity bookEntity = TBookEntity.fromJson(obj);
      datas.add(bookEntity);
    }
    return datas;
  }

  Future<String> getAllBsign() async {
    List<TBookEntity> datas = await getAllBaseData();
    List<String> bsigns = datas.map((e) => e.bsign ?? "").toList();
    bsigns.sort((a,b)=>a.compareTo(b));
    String str = datas.join(",");
    return DxmUtils.md5Str(str);
  }

  void _whereSql(StringBuffer sb,BookParams params){
    String word = params.word ?? "";
    if(word.isNotEmpty){
      sb.write(" and ( t1.bname like '%${word}%' or t1.bchao like '%${word}%' or t1.bauthor like '%${word}%' ) ");
    }

  }
  void _orderBySql(StringBuffer sb){
    sb.write(" order by  t1.border ");
  }

  Future<List<TBookEntity>> queryList(BookParams params) async {
    Database? db = await getDataBase();
    List<TBookEntity> datas = [];
    if(db == null){
      return datas;
    }
    StringBuffer sb =  StringBuffer(" select t1.* from ${TABLE_NAME} t1 where ifnull(t1.bstatus,1) = ${AppConfig.BSTATUS_UP} ");
    _whereSql(sb, params);
    _orderBySql(sb);
    limitSql(sb, params);
    print("SQL:========>${sb.toString()}");
    List<Map<String,Object?>> dbRecords = await db.rawQuery(sb.toString());
    for(Map<String,Object?> obj in dbRecords){
      datas.add(TBookEntity.fromJson(obj));
    }
    return datas;
  }

  Future<int?> countList(BookParams params) async {
    Database? db = await getDataBase();
    if(db == null){
      return 0;
    }
    StringBuffer sb =  StringBuffer(" select count(1) from ${TABLE_NAME} t1 where ifnull(t1.bstatus,1) = ${AppConfig.BSTATUS_UP} ");
    //构建查询
    _whereSql(sb, params);
    return Sqflite.firstIntValue(await db.rawQuery(sb.toString()));
  }

  Future<int> updateSelectiveById(TBookEntity po ) async {
    if(po.id == null){
      po.id = -1;
    }
    Database? db = await getDataBase();
    if(db == null){
      return 0;
    }
    Map<String,dynamic> updateMap = {};
    if(po.bname != null){
      updateMap["${column_bname}"] = po.bname;
    }
    if(po.bauthor != null){
      updateMap["${column_bauthor}"] = po.bauthor;
    }
    if(po.bchao != null){
      updateMap["${column_bchao}"] = po.bchao;
    }
    if(po.bcount != null){
      updateMap["${column_bcount}"] = po.bcount;
    }
    if(po.bstatus != null){
      updateMap["${column_bstatus}"] = po.bstatus;
    }
    if(po.bsign != null){
      updateMap["${column_bsign}"] = po.bsign;
    }
    if(po.phk != null){
      updateMap["${column_phk}"] = po.phk;
    }
    if(po.border != null){
      updateMap["${column_border}"] = po.border;
    }
    if(po.bdesc != null){
      updateMap["${column_bdesc}"] = po.bdesc;
    }
    if(po.tmsec != null){
      updateMap["${column_tmsec}"] = po.tmsec;
    }
    int num = await db.update(TABLE_NAME,updateMap,where: " id = ? ",whereArgs: [po.id]);
    Log.i("更细书籍 ${updateMap} updateNum=${num}");
    return num;
  }

  Future<TBookEntity?> getById(int id) async {
    Database? db = await getDataBase();
    if(db == null){
      return null;
    }
    String sql = "select * from ${TABLE_NAME} where $column_id = $id ";
    List<Map<String,Object?>> datas = await db.rawQuery(sql);
    if(datas.length > 0 ){
      return datas.map((e) => TBookEntity.fromJson(e)).first;
    }
    return null;
  }


}